"""
HTML报告Generate器Module
"""

from datetime import datetime
from typing import Dict, List, Any
from pathlib import Path


class HTMLGenerator:
    """HTMLGenerate器"""
    
    def __init__(self, results_dir: Path):
        self.results_dir = results_dir
    
    def generate(self, analyses: List[Dict], comparison: Dict, 
                summary_data: Dict, images: List, report_gen) -> str:
        """GenerateCompleteHTML"""
        html = self._get_html_header()
        html += f"""
        <h1>Side-Channel Attack Experiment Report</h1>
        <p><strong>Generated:</strong> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
        <p><strong>Results Directory:</strong> {self.results_dir}</p>
"""
        
        if summary_data:
            html += self._generate_summary(summary_data)
        
        html += self._generate_stats(analyses)
        html += self._generate_statistical_significance(analyses, report_gen)
        html += self._generate_comparison(comparison)
        html += self._generate_detailed_table(analyses)
        html += self._generate_insights(analyses, comparison)
        
        if images:
            html += self._generate_images(images, report_gen)
        
        html += self._get_html_footer()
        return html
    
    def _get_html_header(self) -> str:
        """HTML头部"""
        return """<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Side-Channel Attack Experiment Report</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; color: #333; background-color: #f5f5f5; padding: 20px; }
        .container { max-width: 1400px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        h1 { color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 15px; margin-bottom: 30px; }
        h2 { color: #34495e; margin-top: 40px; margin-bottom: 20px; padding-left: 10px; border-left: 4px solid #3498db; }
        h3 { color: #7f8c8d; margin-top: 25px; margin-bottom: 15px; }
        .summary-box { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 25px; border-radius: 8px; margin-bottom: 30px; }
        .summary-box h2 { color: white; border: none; margin: 0 0 15px 0; padding: 0; }
        .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 20px 0; }
        .stat-card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); text-align: center; }
        .stat-value { font-size: 32px; font-weight: bold; color: #3498db; margin: 10px 0; }
        .stat-label { color: #7f8c8d; font-size: 14px; }
        table { width: 100%; border-collapse: collapse; margin: 20px 0; background: white; }
        th { background: #34495e; color: white; padding: 12px; text-align: left; font-weight: 600; }
        td { padding: 10px 12px; border-bottom: 1px solid #ecf0f1; }
        tr:hover { background: #f8f9fa; }
        .success { color: #27ae60; font-weight: bold; }
        .failure { color: #e74c3c; font-weight: bold; }
        .confidence-high { color: #27ae60; }
        .confidence-medium { color: #f39c12; }
        .confidence-low { color: #e74c3c; }
        .progress-bar { width: 100%; height: 25px; background: #ecf0f1; border-radius: 12px; overflow: hidden; margin: 10px 0; }
        .progress-fill { height: 100%; background: linear-gradient(90deg, #3498db, #2ecc71); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 12px; }
        .comparison-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin: 20px 0; }
        .comparison-card { background: #f8f9fa; padding: 20px; border-radius: 8px; border: 1px solid #dee2e6; }
        .comparison-card h4 { color: #495057; margin-bottom: 15px; }
        .badge { display: inline-block; padding: 5px 10px; border-radius: 4px; font-size: 12px; font-weight: bold; margin: 2px; }
        .badge-success { background: #d4edda; color: #155724; }
        .badge-warning { background: #fff3cd; color: #856404; }
        .badge-info { background: #d1ecf1; color: #0c5460; }
        .image-gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px; margin: 20px 0; }
        .image-card { background: white; padding: 15px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
        .image-card img { width: 100%; border-radius: 4px; }
        .image-card h4 { margin: 10px 0; color: #495057; }
        .insights-box { background: #fff8dc; border-left: 4px solid #f39c12; padding: 20px; margin: 20px 0; border-radius: 4px; }
        .insights-box h3 { color: #f39c12; margin-top: 0; }
        .insights-box ul { margin-left: 20px; margin-top: 10px; }
        .insights-box li { margin: 8px 0; }
        .footer { text-align: center; margin-top: 50px; padding-top: 20px; border-top: 1px solid #dee2e6; color: #6c757d; }
    </style>
</head>
<body>
    <div class="container">
"""
    
    def _generate_summary(self, summary: Dict) -> str:
        """Generate实验总结"""
        return f"""
        <div class="summary-box">
            <h2>Experiment Summary</h2>
            <p><strong>Experiment Name:</strong> {summary.get('experiment_name', 'N/A')}</p>
            <p><strong>Execution Time:</strong> {summary.get('execution_time', 'N/A')}</p>
            <p><strong>Total Algorithms:</strong> {summary.get('total_algorithms', 0)}</p>
            <p><strong>Successful:</strong> {summary.get('successful_algorithms', 0)}</p>
        </div>
"""
    
    def _generate_stats(self, analyses: List[Dict]) -> str:
        """Generate整体统计"""
        total_reports = len(analyses)
        total_bytes_tested = sum(a['total_bytes'] for a in analyses)
        total_bytes_recovered = sum(a['success_bytes'] for a in analyses)
        avg_success_rate = sum(a['success_rate'] for a in analyses) / len(analyses) if analyses else 0
        avg_confidence = sum(a['avg_confidence'] for a in analyses) / len(analyses) if analyses else 0
        
        # Calculate模糊Match统计
        total_fuzzy_matches = 0
        fuzzy_total = 0
        for a in analyses:
            fuzzy_info = a.get('fuzzy_match_info', {})
            if fuzzy_info:
                total_fuzzy_matches += fuzzy_info.get('in_top_n_count', 0)
                fuzzy_total += fuzzy_info.get('total_bytes', 0)
        
        avg_fuzzy_rate = total_fuzzy_matches / fuzzy_total if fuzzy_total > 0 else 0
        
        return f"""
        <h2>Overall Statistics</h2>
        <p style="margin: 10px 0; color: #666;">
            <strong>Exact Recovery:</strong> Key bytes correctly identified as the top prediction (no brute-force needed)
            <br><strong>Fuzzy Match:</strong> Key bytes found within Top-N candidates (requires limited brute-force search)
        </p>
        <div class="stats-grid">
            <div class="stat-card">
                <div class="stat-label">Total Reports</div>
                <div class="stat-value">{total_reports}</div>
            </div>
            <div class="stat-card">
                <div class="stat-label">Total Bytes Tested</div>
                <div class="stat-value">{total_bytes_tested}</div>
            </div>
            <div class="stat-card">
                <div class="stat-label">Exact Recovery</div>
                <div class="stat-value">{total_bytes_recovered}</div>
                <div class="stat-label" style="color: #27ae60; font-weight: bold;">{avg_success_rate:.1%} of bytes</div>
            </div>
            <div class="stat-card">
                <div class="stat-label">Fuzzy Match (Top-N)</div>
                <div class="stat-value">{total_fuzzy_matches}</div>
                <div class="stat-label" style="color: #f39c12; font-weight: bold;">{avg_fuzzy_rate:.1%} of bytes</div>
            </div>
            <div class="stat-card">
                <div class="stat-label">Avg Confidence</div>
                <div class="stat-value">{avg_confidence:.3f}</div>
                <div class="stat-label" style="color: #666;">correlation strength</div>
            </div>
        </div>
"""
    
    def _generate_statistical_significance(self, analyses: List[Dict], report_gen) -> str:
        """Generate统计显著性AnalyzePartial"""
        html = """
        <h2>Statistical Significance Analysis</h2>
        <p style="margin: 10px 0; color: #666;">
            <strong>Purpose:</strong> Determine whether the attack results are statistically significant or merely due to random chance.
            <br><strong>Method:</strong> We use binomial test and rank analysis to compare attack performance against random guessing.
            <br><strong>Null Hypothesis (H0):</strong> The attack is equivalent to random guessing.
            <br><strong>Alternative Hypothesis (H1):</strong> The attack is better than random guessing.
        </p>
"""
        
        # ForEachAnalyzeCalculate统计显著性
        for analysis in analyses[:5]:  # Display前5个报告的统计Analyze
            stats_result = report_gen.calculate_statistical_significance(analysis)
            
            is_significant = stats_result['is_significant']
            confidence_level = stats_result['confidence_level']
            p_value = stats_result['p_value']
            interpretation = stats_result['interpretation']
            conclusion = stats_result['conclusion']
            details = stats_result['details']
            
            # According to显著性Settings颜色
            if is_significant:
                card_color = "#d4edda"
                border_color = "#27ae60"
                status_badge = '<span class="badge badge-success">Significant</span>'
            else:
                card_color = "#f8d7da"
                border_color = "#e74c3c"
                status_badge = '<span class="badge badge-danger">Not Significant</span>'
            
            html += f"""
        <div style="background: {card_color}; border-left: 4px solid {border_color}; padding: 15px; margin: 15px 0; border-radius: 4px;">
            <h4 style="margin-top: 0;">{analysis['filename']} {status_badge}</h4>
            <p><strong>Algorithm:</strong> {analysis['algorithm']} | 
               <strong>Leakage Model:</strong> {analysis['leakage_model']} | 
               <strong>Target Operation:</strong> {analysis['target_operation']}</p>
            
            <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin: 15px 0;">
                <div>
                    <strong>P-Value:</strong> {p_value:.6f}<br>
                    <small style="color: #666;">Probability results are due to chance</small>
                </div>
                <div>
                    <strong>Confidence Level:</strong> {confidence_level:.2f}%<br>
                    <small style="color: #666;">Statistical confidence in results</small>
                </div>
                <div>
                    <strong>Observed Rate:</strong> {details['observed_success_rate']:.1%}<br>
                    <small style="color: #666;">vs Random: {details['random_success_rate']:.1%}</small>
                </div>
                <div>
                    <strong>Improvement Factor:</strong> {details['improvement_factor']:.2f}x<br>
                    <small style="color: #666;">Better than random guessing</small>
                </div>
            </div>
            
            <p style="margin: 10px 0;"><strong>Interpretation:</strong> {interpretation}</p>
            <p style="margin: 5px 0; color: #555;"><em>{conclusion}</em></p>
            
            <details style="margin-top: 10px;">
                <summary style="cursor: pointer; color: #3498db;"><strong>Show Detailed Statistics</strong></summary>
                <div style="margin-top: 10px; padding: 10px; background: white; border-radius: 4px;">
                    <table style="width: 100%; font-size: 12px;">
                        <tr>
                            <td><strong>Binomial Test P-Value:</strong></td>
                            <td>{stats_result['p_value_binomial']:.6f}</td>
                            <td><strong>Rank Test P-Value:</strong></td>
                            <td>{stats_result['p_value_rank']:.6f}</td>
                        </tr>
                        <tr>
                            <td><strong>Observed Avg Rank:</strong></td>
                            <td>{details['observed_avg_rank']:.1f}</td>
                            <td><strong>Expected Random Rank:</strong></td>
                            <td>{details['expected_random_rank']:.1f}</td>
                        </tr>
                        <tr>
                            <td><strong>Rank Improvement:</strong></td>
                            <td>{details['rank_improvement']:.1f} positions</td>
                            <td><strong>Effect Size:</strong></td>
                            <td>{details['effect_size']:.2%}</td>
                        </tr>
                        <tr>
                            <td><strong>Valid Ranks Count:</strong></td>
                            <td>{details['valid_ranks_count']}</td>
                            <td><strong>Significance Threshold:</strong></td>
                            <td>p < 0.05</td>
                        </tr>
                    </table>
                    
                    <p style="margin-top: 10px; font-size: 11px; color: #666;">
                        <strong>Statistical Tests Used:</strong>
                        <br>1. <strong>Binomial Test:</strong> Tests whether the proportion of correct values found in Top-N 
                        significantly exceeds the random probability (Top-N/256).
                        <br>2. <strong>Rank Analysis:</strong> Tests whether the average rank of correct values is 
                        significantly lower than the random expectation ((Top-N+1)/2).
                    </p>
                </div>
            </details>
        </div>
"""
        
        return html
    
    def _generate_comparison(self, comparison: Dict) -> str:
        """Generate对比Analyze"""
        html = "<h2>Comparative Analysis</h2>"
        
        best = comparison.get('best_result')
        worst = comparison.get('worst_result')
        
        if best and worst:
            best_fuzzy_info = best.get('fuzzy_match_info', {})
            best_fuzzy_rate = best_fuzzy_info.get('success_rate', 0)
            worst_fuzzy_info = worst.get('fuzzy_match_info', {})
            worst_fuzzy_rate = worst_fuzzy_info.get('success_rate', 0)
            
            html += f"""
        <div class="comparison-grid">
            <div class="comparison-card">
                <h4>Best Result</h4>
                <p><strong>File:</strong> {best['filename']}</p>
                <p><strong>Algorithm:</strong> {best['algorithm']}</p>
                <p><strong>Leakage Model:</strong> {best['leakage_model']}</p>
                <p><strong>Target Operation:</strong> {best['target_operation']}</p>
                <p><strong>Exact Match Rate:</strong> <span class="success">{best['success_rate']:.1%}</span> ({best['success_bytes']}/{best['total_bytes']} bytes)</p>
                <p><strong>Fuzzy Match Rate:</strong> <span style="color: #f39c12;">{best_fuzzy_rate:.1%}</span></p>
                <p><strong>Avg Confidence:</strong> {best['avg_confidence']:.3f}</p>
            </div>
            <div class="comparison-card">
                <h4>Worst Result</h4>
                <p><strong>File:</strong> {worst['filename']}</p>
                <p><strong>Algorithm:</strong> {worst['algorithm']}</p>
                <p><strong>Leakage Model:</strong> {worst['leakage_model']}</p>
                <p><strong>Target Operation:</strong> {worst['target_operation']}</p>
                <p><strong>Exact Match Rate:</strong> <span class="failure">{worst['success_rate']:.1%}</span> ({worst['success_bytes']}/{worst['total_bytes']} bytes)</p>
                <p><strong>Fuzzy Match Rate:</strong> <span style="color: #f39c12;">{worst_fuzzy_rate:.1%}</span></p>
                <p><strong>Avg Confidence:</strong> {worst['avg_confidence']:.3f}</p>
            </div>
        </div>
"""
        
        html += """
        <h3>Performance by Leakage Model</h3>
        <table>
            <tr>
                <th>Leakage Model</th>
                <th>Count</th>
                <th>Avg Success Rate</th>
                <th>Avg Confidence</th>
            </tr>
"""
        
        for model, model_analyses in comparison.get('by_leakage_model', {}).items():
            avg_sr = sum(a['success_rate'] for a in model_analyses) / len(model_analyses)
            avg_conf = sum(a['avg_confidence'] for a in model_analyses) / len(model_analyses)
            html += f"""
            <tr>
                <td><span class="badge badge-info">{model}</span></td>
                <td>{len(model_analyses)}</td>
                <td>{avg_sr:.1%}</td>
                <td>{avg_conf:.3f}</td>
            </tr>
"""
        
        html += "</table>"
        
        html += """
        <h3>Performance by Target Operation</h3>
        <table>
            <tr>
                <th>Target Operation</th>
                <th>Count</th>
                <th>Avg Success Rate</th>
                <th>Avg Confidence</th>
            </tr>
"""
        
        for operation, op_analyses in comparison.get('by_target_operation', {}).items():
            avg_sr = sum(a['success_rate'] for a in op_analyses) / len(op_analyses)
            avg_conf = sum(a['avg_confidence'] for a in op_analyses) / len(op_analyses)
            html += f"""
            <tr>
                <td><span class="badge badge-warning">{operation}</span></td>
                <td>{len(op_analyses)}</td>
                <td>{avg_sr:.1%}</td>
                <td>{avg_conf:.3f}</td>
            </tr>
"""
        
        html += "</table>"
        return html
    
    def _generate_detailed_table(self, analyses: List[Dict]) -> str:
        """GenerateDetailedResult表格"""
        html = """
        <h2>Detailed Results</h2>
        <p style="margin: 10px 0; color: #666;">
            <strong>Note:</strong> 
            <br>- <strong>Exact Match Rate:</strong> Percentage of key bytes where the top prediction is correct
            <br>- <strong>Fuzzy Match Rate:</strong> Percentage of key bytes found within Top-N candidates (requires brute-force search)
        </p>
        <table>
            <tr>
                <th>File</th>
                <th>Algorithm</th>
                <th>Leakage Model</th>
                <th>Target Op</th>
                <th>Exact Match Rate</th>
                <th>Fuzzy Match Rate (Top-N)</th>
                <th>Avg Confidence</th>
            </tr>
"""
        
        # 按exact matchAndfuzzy match综合Sort
        sorted_analyses = sorted(analyses, key=lambda x: (x['success_rate'], x.get('fuzzy_match_info', {}).get('success_rate', 0)), reverse=True)
        
        for analysis in sorted_analyses:
            exact_rate = analysis['success_rate']
            conf_class = 'confidence-high' if analysis['avg_confidence'] > 0.3 else \
                        'confidence-medium' if analysis['avg_confidence'] > 0.2 else 'confidence-low'
            
            # 模糊MatchInformation
            fuzzy_info = analysis.get('fuzzy_match_info', {})
            fuzzy_count = fuzzy_info.get('in_top_n_count', 0)
            fuzzy_total = fuzzy_info.get('total_bytes', analysis['total_bytes'])
            fuzzy_rate = fuzzy_count / fuzzy_total if fuzzy_total > 0 else 0
            avg_rank = fuzzy_info.get('avg_rank', 0)
            
            # 精确Match颜色
            exact_color = "background: linear-gradient(90deg, #27ae60, #2ecc71);" if exact_rate > 0 else "background: #e74c3c;"
            # 模糊Match颜色
            fuzzy_color = "background: linear-gradient(90deg, #f39c12, #e67e22);" if fuzzy_rate > 0 else "background: #95a5a6;"
            
            html += f"""
            <tr>
                <td>{analysis['filename']}</td>
                <td><span class="badge badge-info">{analysis['algorithm']}</span></td>
                <td>{analysis['leakage_model']}</td>
                <td>{analysis['target_operation']}</td>
                <td>
                    <div class="progress-bar">
                        <div class="progress-fill" style="width: {max(exact_rate*100, 5)}%; {exact_color}">
                            {exact_rate:.1%}
                        </div>
                    </div>
                    <small>{analysis['success_bytes']}/{analysis['total_bytes']} bytes</small>
                </td>
                <td>
                    <div class="progress-bar">
                        <div class="progress-fill" style="width: {max(fuzzy_rate*100, 5)}%; {fuzzy_color}">
                            {fuzzy_rate:.1%}
                        </div>
                    </div>
                    <small>{fuzzy_count}/{fuzzy_total} bytes (Avg Rank: {avg_rank:.1f})</small>
                </td>
                <td class="{conf_class}">{analysis['avg_confidence']:.3f}</td>
            </tr>
"""
        
        html += "</table>"
        
        # AddEach报告的Detailed字节Information
        html += self._generate_byte_details_tables(sorted_analyses)
        
        return html
    
    def _generate_byte_details_tables(self, analyses: List[Dict]) -> str:
        """GenerateEach报告的字节DetailedInformation"""
        html = """
        <h2>Byte-Level Detailed Analysis</h2>
        <p style="margin: 10px 0; color: #666;">
            <strong>Note:</strong> This section shows the attack results for each key byte, including:
            <br>- <strong>Correct Value:</strong> The actual key byte (shown for reference)
            <br>- <strong>Best Guess:</strong> The attack's top prediction
            <br>- <strong>Status:</strong> Match (exact), Fuzzy (in Top-N), or Miss (not found)
            <br>- <strong>Top-10 Candidates:</strong> The most likely key byte values, sorted by correlation/confidence
            <br>- In the candidate list, <span style="color: #27ae60; font-weight: bold;">green entries</span> indicate correct key bytes found by the attack
        </p>
"""
        
        for analysis in analyses[:3]:  # 只展示前3个报告的DetailedInformation
            fuzzy_info = analysis.get('fuzzy_match_info', {})
            rankings = fuzzy_info.get('rankings', [])
            byte_details = analysis.get('byte_details', [])
            correct_key_bytes = analysis.get('correct_key_bytes', [])
            correct_key_hex = analysis.get('correct_key', 'Unknown')
            
            if not byte_details:
                continue
            
            html += f"""
        <h3>{analysis['filename']}</h3>
        <p style="margin: 5px 0; color: #666;">
            <strong>Algorithm:</strong> {analysis['algorithm'].upper()} | 
            <strong>Leakage Model:</strong> {analysis['leakage_model']} | 
            <strong>Target Operation:</strong> {analysis['target_operation']}
            <br><strong>Correct Key:</strong> <code style="background: #f0f0f0; padding: 2px 5px;">{correct_key_hex}</code>
        </p>
        <table>
            <tr>
                <th>Byte Index</th>
                <th>Correct Value</th>
                <th>Best Guess</th>
                <th>Status</th>
                <th>Confidence</th>
                <th>Correct Rank</th>
                <th>Top-10 Candidates (Value: Confidence)</th>
            </tr>
"""
            
            for i, byte_detail in enumerate(byte_details):
                byte_idx = byte_detail['index']
                success = byte_detail['success']
                confidence = byte_detail['confidence']
                best_hyp = byte_detail.get('best_hypothesis', 0)
                top_candidates = byte_detail.get('top_candidates', [])
                
                # 获取正确的Key字节值
                correct_value = correct_key_bytes[i] if i < len(correct_key_bytes) else None
                correct_value_display = f"0x{correct_value:02x}" if correct_value is not None else "N/A"
                
                # 获取排名
                rank = rankings[i] if i < len(rankings) else None
                rank_display = f"<strong>#{rank}</strong>" if rank is not None else '<span style="color: #999;">Not in Top-{}</span>'.format(analysis['top_n'])
                rank_class = "success" if rank is not None else "failure"
                
                # 判断best guessYesNo正确
                best_correct = (correct_value is not None and best_hyp == correct_value)
                best_style = "font-weight: bold; color: #27ae60;" if best_correct else ""
                
                status_badge = '<span class="badge badge-success">Exact Match</span>' if success else \
                              '<span class="badge badge-warning">Fuzzy Match</span>' if rank is not None else \
                              '<span class="badge badge-danger">Miss</span>'
                
                # Format化Top-10候选
                candidates_str = ""
                for idx, (cand_val, cand_conf) in enumerate(top_candidates[:10], 1):
                    # CheckCurrent候选YesNoYes正确值
                    is_correct = (correct_value is not None and cand_val == correct_value)
                    
                    if is_correct:
                        # 正确值用绿色高亮
                        candidates_str += f'<span style="font-weight: bold; color: #27ae60; background: #d4edda; padding: 1px 3px; border-radius: 3px;">'
                        candidates_str += f'{idx}. 0x{cand_val:02x}: {cand_conf:.3f} [MATCH]'
                        candidates_str += f'</span><br>'
                    elif idx == 1:
                        # First个候选（但Not正确）用深色
                        candidates_str += f'<span style="font-weight: bold; color: #333;">'
                        candidates_str += f'{idx}. 0x{cand_val:02x}: {cand_conf:.3f}'
                        candidates_str += f'</span><br>'
                    else:
                        # 其他候选
                        candidates_str += f'<span style="color: #666;">'
                        candidates_str += f'{idx}. 0x{cand_val:02x}: {cand_conf:.3f}'
                        candidates_str += f'</span><br>'
                
                html += f"""
            <tr>
                <td><strong>Byte {byte_idx}</strong></td>
                <td style="font-family: monospace; font-weight: bold;">{correct_value_display}</td>
                <td style="font-family: monospace; {best_style}">0x{best_hyp:02x}</td>
                <td>{status_badge}</td>
                <td>{confidence:.3f}</td>
                <td class="{rank_class}">{rank_display}</td>
                <td style="font-size: 11px; line-height: 1.6; font-family: monospace;">{candidates_str}</td>
            </tr>
"""
            
            html += "</table>"
        
        return html
    
    def _generate_insights(self, analyses: List[Dict], comparison: Dict) -> str:
        """Generate关键洞察"""
        html = """
        <h2>Key Insights</h2>
        <div class="insights-box">
            <h3>Analysis Findings</h3>
            <ul>
"""
        
        insights = []
        
        by_model = comparison.get('by_leakage_model', {})
        if by_model:
            model_perfs = {
                model: sum(a['success_rate'] for a in analyses_list) / len(analyses_list)
                for model, analyses_list in by_model.items()
            }
            best_model = max(model_perfs.items(), key=lambda x: x[1])
            insights.append(f"<strong>Best Leakage Model:</strong> {best_model[0]} with average success rate of {best_model[1]:.1%}")
        
        by_operation = comparison.get('by_target_operation', {})
        if by_operation:
            op_perfs = {
                op: sum(a['success_rate'] for a in analyses_list) / len(analyses_list)
                for op, analyses_list in by_operation.items()
            }
            best_op = max(op_perfs.items(), key=lambda x: x[1])
            insights.append(f"<strong>Best Target Operation:</strong> {best_op[0]} with average success rate of {best_op[1]:.1%}")
        
        full_success = sum(1 for a in analyses if a['success_rate'] == 1.0)
        if full_success > 0:
            insights.append(f"<strong>Complete Success:</strong> {full_success} reports achieved 100% exact key recovery")
        
        partial_success = sum(1 for a in analyses if 0 < a['success_rate'] < 1.0)
        if partial_success > 0:
            insights.append(f"<strong>Partial Success:</strong> {partial_success} reports achieved partial key recovery")
        
        fuzzy_rates = []
        for a in analyses:
            fuzzy_info = a.get('fuzzy_match_info', {})
            if fuzzy_info and fuzzy_info.get('total_bytes', 0) > 0:
                fuzzy_rate = fuzzy_info.get('in_top_n_count', 0) / fuzzy_info.get('total_bytes', 1)
                fuzzy_rates.append(fuzzy_rate)
        
        if fuzzy_rates:
            avg_fuzzy_rate = sum(fuzzy_rates) / len(fuzzy_rates)
            insights.append(f"<strong>Fuzzy Match Rate:</strong> On average, {avg_fuzzy_rate:.1%} of correct key bytes appear in Top-N predictions")
        
        avg_ranks = [a.get('fuzzy_match_info', {}).get('avg_rank', 0) for a in analyses 
                    if a.get('fuzzy_match_info', {}).get('avg_rank', 0) > 0]
        if avg_ranks:
            overall_avg_rank = sum(avg_ranks) / len(avg_ranks)
            insights.append(f"<strong>Average Ranking:</strong> When correct key bytes appear in Top-N, they rank at position {overall_avg_rank:.1f} on average")
        
        for insight in insights:
            html += f"<li>{insight}</li>\n"
        
        html += """
            </ul>
        </div>
"""
        return html
    
    def _generate_images(self, images: List, report_gen) -> str:
        """Generate图像画廊"""
        html = """
        <h2>Visualization Gallery</h2>
        <div class="image-gallery">
"""
        
        for img_path in sorted(images):
            img_base64 = report_gen.image_to_base64(img_path)
            if img_base64:
                html += f"""
            <div class="image-card">
                <h4>{img_path.stem}</h4>
                <img src="data:image/png;base64,{img_base64}" alt="{img_path.name}">
            </div>
"""
        
        html += "</div>"
        return html
    
    def _get_html_footer(self) -> str:
        """HTML页脚"""
        return """
        <div class="footer">
            <p>Generated by Side-Channel Attack Experiment Report Generator</p>
            <p>Cryptographic Side-Channel Analysis Research</p>
        </div>
    </div>
</body>
</html>
"""
